﻿using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using Medianamik.Core;
using Medianamik.Core.DAL.Repositories;
using Medianamik.Core.Sugar;
using Medianamik.UI.Controls;
using Medianamik.UI.Web.MVP.View;
using Telerik.Web.UI;

namespace Medianamik.UI.Web.MVP.Presentation
{
    public abstract class ModulePresenterWithGrid<TItem, TView, TRepository, TNodeTypeRepository, TBaseTypeRepository> :
        ModulePresenterWithRepository<TItem, TView, TRepository, TNodeTypeRepository, TBaseTypeRepository>
        where TItem : class, IMedianamikDTO
        where TView : IModuleViewWithGrid
        where TRepository : class, IMedianamikRepository<TItem>
        where TNodeTypeRepository : class, INodeTypeRepository
        where TBaseTypeRepository : class, IMedianamikRepository<IMedianamikDTOWithName>
    {
        public ModulePresenterWithGrid(TView view, TRepository repository,
            TNodeTypeRepository nodeTypeRepository,
            TBaseTypeRepository baseTypeRepository)
            : base(view, repository, nodeTypeRepository, baseTypeRepository)
        {

        }

        protected override void Initialize(object sender, EventArgs e)
        {
            View.Grid.GridDataBound += GridDataBound;
            View.Grid.ActivationStatusChanged += ActivationStatusChanged;
            View.Grid.NodeDeleted += NodeDeleted;
            View.Grid.PageIndexChanged += GridPageIndexChanged;
            View.Grid.LockRequestFailed += LockRequestFailed;
            View.Grid.PageSizeChanged += GridPageSizeChanged;
            View.Grid.OrderChanged += OrderChanged;

            base.Initialize(sender, e);
        }

        void GridPageSizeChanged(object sender, GridPageSizeChangedEventArgs e)
        {
            PageSizeChanged(sender, new NumericalEventArgs(e.NewPageSize));
        }

        protected virtual void GridPageIndexChanged(object sender, GridPageChangedEventArgs e)
        {
            PageIndexChanged(sender, new NumericalEventArgs(e.NewPageIndex + 1));
        }

        protected virtual void SetCreatedOnGridItemHtml(ITextControl createdOnGridItem, TItem gridItem)
        {
            if (createdOnGridItem != null)
                createdOnGridItem.Text = gridItem.CreatedOn.ToString("D", CurrentUICulture);
        }

        protected virtual void GridDataBound(object sender, GridItemEventArgs e)
        {
            if (e.Item.ItemType == GridItemType.Item ||
                e.Item.ItemType == GridItemType.AlternatingItem)
            {
                var element = (GridDataItem)e.Item;

                if (element.DataItem != null)
                {
                    var baseType = element.DataItem as TItem;

                    if (baseType != null)
                    {
                        var existInCurrentCulture = baseType.CultureName == CurrentEditionCulture.Name;

                        SetCustomGridColumns(e.Item, baseType, existInCurrentCulture);
                        SetGridRowCSS(element, baseType, existInCurrentCulture);
                    }
                }
            }
        }

        protected virtual void SetGridRowCSS(GridDataItem item, TItem element, bool existInCurrentCulture)
        {
            if (!existInCurrentCulture)
                item.CssClass = "rgRow ElementNonTraduit";
            else if (element.HasModifications && 
                NodeTypeManager.GetNodeType(element.TypeId).IsVersioned)
            {
                item.CssClass = "rgRow ElementBrouillon";
            }
        }

        protected virtual void SetCustomGridColumns(GridItem item, TItem element, bool existInCurrentCulture)
        {
            if (View.Filters.HasFilter(ModuleViewFilters.StartDate))
                SetCreatedOnGridItemHtml(item.FindControl("CreatedOnGridItem") as Literal, element);

            var childCount = NodeManager.GetChildNodeCount(element.NodeId);

            SetEditButton(item.FindControl("EditButton") as LockButton, element, existInCurrentCulture);
            SetDeleteButton(item.FindControl("deleteNodeButton") as CheckLockButton, element, existInCurrentCulture, childCount);
            SetDiffButton(item.FindControl("DiffLinkButton") as LockButton, element, existInCurrentCulture);
            SetRevisionButton(item.FindControl("RevisionButton") as LockButton, element, existInCurrentCulture);
            SetActivationButton(item.FindControl("btnNodeActivation") as NodeActivationButton, element, existInCurrentCulture);
            SetNameColumn(item.FindControl("NameGridItem") as Literal, element, existInCurrentCulture, childCount);
        }

        protected virtual void SetNameColumn(ITextControl nameGridItem, TItem element, bool existInCurrentCulture, int childCount)
        {
            var medianamikDTO = element as IMedianamikDTO;

            if (medianamikDTO != null && nameGridItem != null)
            {
                var namedElement = SetNameColumn(element);
                var medianamikDTOWithName = element as IMedianamikDTOWithName;
                if (medianamikDTOWithName != null)
                    namedElement = medianamikDTOWithName.Name;

                var name = existInCurrentCulture ?
                    namedElement : String.Concat("[&nbsp;", namedElement, "&nbsp;]");

                if (ChildrenListingPageUrl != null && NodeTypeRepository.NodesOfTypeCanHaveChildren(element.TypeId))
                {
                    nameGridItem.Text = "<a href=\"" + BuildUrl(ChildrenListingPageUrl, ParentNodeIdParamName, element.NodeId) +
                        "\">" + name + "</a>" + FormatChildItemsCount(childCount);
                }
                else
                {
                    nameGridItem.Text = name;
                }
            }
        }

        protected virtual string SetNameColumn(TItem element)
        {
            return element.NodeId.ToString();
        }

        protected virtual string ChildrenListingPageUrl
        {
            get { return View.ChildrenListingPageUrl; }
        }

        protected virtual void SetEditButton(LockButton editButton, TItem element, bool existInCurrentCulture)
        {
            if (editButton != null)
            {
                editButton.NavigateUrl = BuildUrl(View.EditPageUrl,
                    NodeIdParamName, element.NodeId).AddParam(HideTreeViewParamName, true);

                if(!existInCurrentCulture)
                {
                    editButton.ImageUrl = "/Medianamik/images/Icones/Ico_Plus.gif";
                }
            }
        }

        protected virtual string NodeIdParamName
        {
            get { return View.NodeIdParamName; }
        }

        protected virtual string ParentNodeIdParamName
        {
            get { return View.ParentNodeIdParamName; }
        }

        protected virtual string HideTreeViewParamName
        {
            get { return View.HideTreeViewParamName; }
        }

        protected virtual void SetDeleteButton(CheckLockButton deleteButton, TItem element,
            bool existInCurrentCulture, int childCount)
        {
            if (deleteButton != null)
            {
                if (!existInCurrentCulture || childCount > 0)
                    deleteButton.Enabled = false;
            }
        }

        protected virtual void SetDiffButton(LockButton diffButton, TItem element, bool existInCurrentCulture)
        {
            if (diffButton != null)
            {
                if (!existInCurrentCulture)
                    diffButton.Enabled = false;
            }
        }

        protected virtual void SetRevisionButton(LockButton revisionButton, TItem element, bool existInCurrentCulture)
        {
            if (revisionButton != null)
            {
                if (!existInCurrentCulture || !NodeTypeManager.GetNodeType(element.TypeId).IsVersioned)
                    revisionButton.Enabled = false;
            }
        }

        protected virtual void SetActivationButton(NodeActivationButton activationButton, TItem element, bool existInCurrentCulture)
        {
            if (activationButton != null)
            {
                if (!existInCurrentCulture)
                    activationButton.Enabled = false;
            }
        }

        protected override void Bind()
        {
            base.Bind();

            View.Grid.UpdateGrid();
        }
    }
}